//          _/             _/_/
//        _/_/           _/_/_/
//      _/_/_/_/         _/_/_/
//      _/_/_/_/_/       _/_/_/              ____________________________________________ 
//      _/_/_/_/_/       _/_/_/             /                                           / 
//      _/_/_/_/_/       _/_/_/            /                                 28F00AP30 / 
//      _/_/_/_/_/       _/_/_/           /                                           /  
//      _/_/_/_/_/_/     _/_/_/          /                                     1Gbit / 
//      _/_/_/_/_/_/     _/_/_/         /                                single die / 
//      _/_/_/ _/_/_/    _/_/_/        /                                           / 
//      _/_/_/  _/_/_/   _/_/_/       /                  Verilog Behavioral Model / 
//      _/_/_/   _/_/_/  _/_/_/      /                               Version 1.7 / 
//      _/_/_/    _/_/_/ _/_/_/     /                                           /
//      _/_/_/     _/_/_/_/_/_/    /           Copyright (c) 2010 Numonyx B.V. / 
//      _/_/_/      _/_/_/_/_/    /___________________________________________/ 
//      _/_/_/       _/_/_/_/      
//      _/_/          _/_/_/  
// 
//     
//             NUMONYX              

// Include General define
`include "include/def.h"
// Include Characterization of the device
`include "include/data.h"
// Include CUI command define
`include "include/TimingData.h"
`define DEBUG

`ifdef DEBUG
        module mytask(Enable,Write,Read,Latch,AddrOut,DataOut,DataIn,Clock);
        output Clock;
        reg Clock = 0;
`else        
        module mytask(Enable,Write,Read,Latch,AddrOut,DataOut,DataIn);
`endif
        output Enable, Write,Read,Latch;
        output [`ADDRBUS_dim - 1 : 0] AddrOut;
        output [`DATABUS_dim - 1 : 0] DataOut;
        input [`DATABUS_dim - 1 : 0] DataIn;

        reg Enable, Write,Read,Latch;
        reg [`ADDRBUS_dim - 1 : 0] AddrOut;
        reg [`DATABUS_dim - 1 : 0] DataOut;
 
           
        initial
           begin

               fork
                 #5   AddrOut   = `ADDRBUS_dim'hZZZZZZ;
                 #5   DataOut   = `DATABUS_dim'hzzzz;
                 #5   Write     = 1'b1;
                 #5   Read      = 1'b1;
                 #5   Enable    = 1'b1;
                 #5   Latch     = 1'b1;
                join
           end



//###########################################
//## Proc read_m {add }
//## Reads a value at an address in the memory
//###########################################
// read_m 

        task read_m;  // Read Memory Array

        input [`ADDRBUS_dim - 1:0] addr;

        begin
                fork
                 #5   AddrOut   = `ADDRBUS_dim'hZZZZZZ;
                 #5   DataOut   = `DATABUS_dim'hzzzz;
                 #5   Enable    = 1'b1;
                 #5   Write     = 1'b1;
                 #5   Read      = 1'b1;
                 #5   Latch     = 1'b0;
                join

        #50   AddrOut   = addr;
        #60   Enable = 1'b0;
        #3    Latch  = 1'b0;                           
//!        #10    Latch  = 1'b1;                      
         #5     Read   = 1'b0;
//!        #50   AddrOut   = `ADDRBUS_dim'hZZZZZZ;   
        #250   Read   = 1'b1;
               AddrOut   = `ADDRBUS_dim'hZZZZZZ;
        #15    Enable = 1'b1; 
                   #10   DataOut   = `DATABUS_dim'hzzzz; 

        #1000 ;
        
        end
        endtask

        task read_m_nd;  // Read Memory Array

        input [`ADDRBUS_dim - 1:0] addr;

        begin
                fork
               //  #5   AddrOut   = `ADDRBUS_dim'hZZZZZZ;
                 #5   DataOut   = `DATABUS_dim'hzzzz;
                 #5   Enable    = 1'b1;
                 #5   Write     = 1'b1;
                 #5   Read      = 1'b1;
                 #5   Latch     = 1'b0;
                join

        #50   AddrOut   = addr;
        #60   Enable = 1'b0;
        #3    Latch  = 1'b0;                           
//!        #10    Latch  = 1'b1;                      
         #5     Read   = 1'b0;
//!        #50   AddrOut   = `ADDRBUS_dim'hZZZZZZ;   
        #250   Read   = 1'b1;
        //#32   Read   = 1'b1;
           //    AddrOut   = `ADDRBUS_dim'hZZZZZZ;
        #15    Enable = 1'b1; 
                   #10   DataOut   = `DATABUS_dim'hzzzz; 

//        #1000 ;
        
        end
        endtask


       task read_m_new;  // Read Memory Array

        input [`ADDRBUS_dim - 1:0] addr;

        begin
                fork
//!                 #5   AddrOut   = `ADDRBUS_dim'hZZZZZZ;
                 #5   DataOut   = `DATABUS_dim'hzzzz;
                 #5   Enable    = 1'b1;
                 #5   Write     = 1'b1;
                 #5   Read      = 1'b1;
                 #5   Latch     = 1'b0;
                join

        #1000   AddrOut   = addr;
        #60   Enable = 1'b0;
//!        #3    Latch  = 1'b0;                           
//!        #10    Latch  = 1'b1;                      
         #25     Read   = 1'b0;
//!        #50   AddrOut   = `ADDRBUS_dim'hZZZZZZ;   
        #155   Read   = 1'b1;
        #15    Enable = 1'b1; 
                   #10   DataOut   = `DATABUS_dim'hzzzz; 

        #1000 ;
        
        end
        endtask


//###########################################
//## Proc read_lwezero {add }
//## Reads a value at an address in the memory
//##########################################

        task read_lwzero;  
        input [`ADDRBUS_dim - 1:0] addr;

        begin
                fork
                 #5   AddrOut   = `ADDRBUS_dim'hZZZZZZ;
                 #5   DataOut   = `DATABUS_dim'hzzzz;
                 #5   Enable    = 1'b1;
                 #5   Write     = 1'b1;
                 #5   Read      = 1'b1;
                 #5   Latch     = 1'b1;
                join

        #50   AddrOut   = addr;
        #60   Enable = 1'b0;
              Latch  = 1'b0;                           
        #10   Latch  = 1'b1;                      
              Read   = 1'b0;                     
        #60   AddrOut   = `ADDRBUS_dim'hZZZZZZ;   
        #125    Read   = 1'b1;
        #15   Enable = 1'b1;                       
        #10   DataOut   = `DATABUS_dim'hzzzz;     
        #1000 ;
        
        end
        endtask


//###########################################
//## Proc write {add data}
//## Write a value to an address in the memory chip enable controlled
//###########################################
// Write_ce                   
     
        task write_ce;  // Word/Byte Program

        input [`ADDRBUS_dim - 1 : 0] addr;
        input [`DATABUS_dim - 1 : 0] data;


        begin
        
                fork
                 #5   AddrOut   = `ADDRBUS_dim'hZZZZZZ;
                 #5   DataOut   = `DATABUS_dim'hzzzz;
                 #5   Write     = 1'b1;
                 #5   Read      = 1'b1;
                 #5   Enable    = 1'b1;
                 #5   Latch     = 1'b1;
                join

        #50   AddrOut= addr;
        #40   Enable = 1'b0;
        #3    Latch  = 1'b0;
              Write  = 1'b0;
        #10    Latch  = 1'b1;
        #10   DataOut= data;     
        #50   Write = 1'b1;
        #0    Enable = 1'b1;
        #5    DataOut   = `DATABUS_dim'hzzzz;
              AddrOut   = `ADDRBUS_dim'hZZZZZZ;
        #1000 ;
        
        end
        endtask

//#############################################################
//## Proc write_lwzero {add data}
//## Write a value to an address in the memory chip enable controlled
//#############################################################

task write_celwzero;  // Word/Byte Program

        input [`ADDRBUS_dim - 1 : 0] addr;
        input [`DATABUS_dim - 1 : 0] data;


        begin
        
                fork
                 #5   AddrOut   = `ADDRBUS_dim'hZZZZZZ;
                 #5   DataOut   = `DATABUS_dim'hzzzz;
                 #5   Write     = 1'b1;
                 #5   Read      = 1'b1;
                 #5   Enable    = 1'b1;
                 #5   Latch     = 1'b1;
                join

        #50   AddrOut= addr;
        #5    Enable = 1'b0;
              Latch  = 1'b0;
              Write  = 1'b0;
        #10   Latch  = 1'b1;
        #10   DataOut= data;     
                      #50   Write = 1'b1;
        #0    Enable = 1'b1;
        #5    DataOut   = `DATABUS_dim'hzzzz;
AddrOut   = `ADDRBUS_dim'hZZZZZZ;

        #1000 ;
        
        end
        endtask

//#############################################################
// procedure check_auto (add data}
//## Reads a value at an address in the memmory
//## and generates an error
//#############################################################

task check_auto; 

        input [`ADDRBUS_dim - 1 : 0] addr;
        input [`DATABUS_dim - 1 : 0] data_exp;
        reg [`DATABUS_dim - 1 : 0] read_value;

        begin
                fork
                 #5   AddrOut   = `ADDRBUS_dim'hZZZZZZ;
                 #5   DataOut   = `DATABUS_dim'hzzzz;
                 #5   read_value= `DATABUS_dim'hzzzz;
                 #5   Write     = 1'b1;
                 #5   Read      = 1'b1;
                 #5   Enable    = 1'b1;
                 #5   Latch     = 1'b1;
                join
         
        #50  AddrOut= addr;    
        #60  Enable = 1'b0;
             Latch  = 1'b0;
        #10  Latch  = 1'b1;
             Read   = 1'b0;                      
             #70  read_value = DataIn;
        #20  AddrOut   = `ADDRBUS_dim'hZZZZZZ;   
        #25  Read   = 1'b1;
        #15  Enable = 1'b1;                       

              $display("read_value is %h\n", read_value);
              $display(" expected data  %h\n",data_exp);
        if (read_value ==  `DATABUS_dim'hzzzz )
            $display ("!!!! Warning : Reading 0xZZZZ value");
        else if (read_value == data_exp)       
               $display ("read Ok");
        else   
           $display("---- Read error ---- "); 
        end
        endtask

//################################################
//## Proc wait_pec_idle {}
//## This procedure reads the status register every 100ns 
//## until it is in idle mode
//################################################

task wait_pec_idle;
        input [`ADDRBUS_dim - 1 : 0] addr;
        reg [`DATABUS_dim - 1 : 0] status_reg_value;

    begin
              fork
                 #5   AddrOut          = `ADDRBUS_dim'hZZZZZZ;
                 #5   status_reg_value = `DATABUS_dim'hFFFF;
                 #5   Write            = 1'b1;
                 #5   Read             = 1'b1;
                 #5   Enable           = 1'b1;
                 #5   Latch            = 1'b1;
                join

            $display ("!!!!wait pec_idle !!!!!");
            while  (status_reg_value >=`DATABUS_dim'h0080 )        
        begin 
        #40   AddrOut   = addr;
              $display("status_reg_value=%h\n", status_reg_value);
        #5    Enable = 1'b0;
        #3    Latch  = 1'b0;                           
        #10    Latch  = 1'b1;                      //t_ELLH=10, t_LLH=7
              Read   = 1'b0;
        #70   status_reg_value = DataIn;         
        #20   AddrOut   = `ADDRBUS_dim'hZZZZZZ;   
        #25   Read   = 1'b1;
        #15   Enable = 1'b1;                       
        #100  $display("status_reg_value=%h\n", status_reg_value);
        end
    end
    endtask
                     


//------------------------------------------
//   proc Program {} {}
//   write 40h 
//-----------------------------------------

        task program;  

        input [`ADDRBUS_dim - 1 : 0] addr;
        input [`DATABUS_dim - 1 : 0] data;

        begin

                 fork
                 #5   AddrOut   = `ADDRBUS_dim'hZZZZZZ;
                 #5   DataOut   = `DATABUS_dim'hzzzz;
                 #50   Write     = 1'b1;
                 #5   Read      = 1'b1;
                 #5   Enable    = 1'b1;
                 #5   Latch     = 1'b1;
                join

        #50   AddrOut= addr;    
        #5    Enable = 1'b0;
        #3    Latch  = 1'b0;
              Write  = 1'b0;
        #10    Latch  = 1'b1;
        #10   DataOut= `DATABUS_dim'h0040;      
        #50   Write  = 1'b1;
        #5    Enable = 1'b1;
        #10   DataOut= `DATABUS_dim'hzzzz;
        #40   AddrOut= addr;                   // Any address in the block
        #5    Enable = 1'b0;                   //t_ELEH=40
        #3    Latch  = 1'b0;
              Write  = 1'b0;                 
        #10    Latch  = 1'b1;
        #10   DataOut= data;
        #50   Write  = 1'b1;                  //t_WHEL=20, t_DVEH=40
        #5    Enable = 1'b1;
        #10   DataOut= `DATABUS_dim'hzzzz;
               AddrOut   = `ADDRBUS_dim'hZZZZZZ;
        #1000 ;
        end
        endtask


        task program_prova;  

        input [`ADDRBUS_dim - 1 : 0] addr;
        input [`DATABUS_dim - 1 : 0] data;

        begin

                 fork
                 #5   AddrOut   = `ADDRBUS_dim'hZZZZZZ;
                 #5   DataOut   = `DATABUS_dim'hzzzz;
                 #50   Write     = 1'b1;
                 #5   Read      = 1'b1;
                 #5   Enable    = 1'b1;
                 #5   Latch     = 1'b0;
                join

        #50   AddrOut= addr;    
        #15    Enable = 1'b0;
//!        #3    Latch  = 1'b0;
        #15      Write  = 1'b0;
//!        #10    Latch  = 1'b1;
        #10   DataOut= `DATABUS_dim'h0040;      
        #50   Write  = 1'b1;
        #15    Enable = 1'b1;
        #21   DataOut= `DATABUS_dim'hzzzz;
        #40   AddrOut= addr;                   // Any address in the block
        #15    Enable = 1'b0;                   //t_ELEH=40
//!        #3    Latch  = 1'b0;
        #15       Write  = 1'b0;                 
//!        #10    Latch  = 1'b1;
        #10   DataOut= data;
        #50   Write  = 1'b1;                  //t_WHEL=20, t_DVEH=40
        #15    Enable = 1'b1;
        #21  DataOut= `DATABUS_dim'hzzzz;
        #1000 ;
        end
        endtask

//------------------------------------------
//   proc block_erase {}
//   write 20h D0h
//-----------------------------------------
// Block Erase 

        task block_erase;  

        input [`ADDRBUS_dim - 1 : 0] addr;

        begin

                 fork
                 #5   AddrOut   = `ADDRBUS_dim'hZZZZZZ;
                 #5   DataOut   = `DATABUS_dim'hzzzz;
                 #5   Write     = 1'b1;
                 #5   Read      = 1'b1;
                 #5   Enable    = 1'b1;
                 #5   Latch     = 1'b1;
                join

        #50   AddrOut= addr;    
        #5    Enable = 1'b0;
        #3    Latch  = 1'b0;
              Write  = 1'b0;
        #10    Latch  = 1'b1;
        #10   DataOut= `DATABUS_dim'h0020;      
        #50   Write  = 1'b1;
              Enable = 1'b1;
        #10   DataOut= `DATABUS_dim'hzzzz;
        #50   AddrOut= addr;                   // Any address in the block
        #30   Enable = 1'b0;                   //t_ELEH=40
        #3    Latch  = 1'b0;
              Write  = 1'b0;                 
        #10    Latch  = 1'b1;
        #10   DataOut= `DATABUS_dim'h00D0;
        #50   Write  = 1'b1;                  //t_WHEL=20, t_DVEH=40
              Enable = 1'b1;
        #10   DataOut= `DATABUS_dim'hzzzz;
              AddrOut   = `ADDRBUS_dim'hZZZZZZ;
        #1000 ;
        
        end
        endtask

//------------------------------------------
//   proc blank check {}
//   write 20h D0h
//-----------------------------------------
// Blank Check 

        task blank_check;  

        input [`ADDRBUS_dim - 1 : 0] addr;

        begin

                 fork
                 #5   AddrOut   = `ADDRBUS_dim'hZZZZZZ;
                 #5   DataOut   = `DATABUS_dim'hzzzz;
                 #5   Write     = 1'b1;
                 #5   Read      = 1'b1;
                 #5   Enable    = 1'b1;
                 #5   Latch     = 1'b1;
                join
        #50   AddrOut= addr;    
        #5    Enable = 1'b0;
        #3    Latch  = 1'b0;
              Write  = 1'b0;
        #10    Latch  = 1'b1;
        #10   DataOut= `DATABUS_dim'h00BC;      
        #50   Write  = 1'b1;
              Enable = 1'b1;
        #10   DataOut= `DATABUS_dim'hzzzz;
             
        #50   AddrOut= addr;                   // Any address in the block
        
        #30   Enable = 1'b0;                   //t_ELEH=40
        #3    Latch  = 1'b0;
              Write  = 1'b0;                 
        #10    Latch  = 1'b1;
        #10   DataOut= `DATABUS_dim'h00D0;
        #50   Write  = 1'b1;                  //t_WHEL=20, t_DVEH=40
              Enable = 1'b1;
        #10   DataOut= `DATABUS_dim'hzzzz;
              AddrOut   = `ADDRBUS_dim'hZZZZZZ;
        #1000 ;
        
        end
        endtask


//------------------------------------------
//   proc read_array
//   write  BKA FFh 
//------------------------------------------

        task read_array;  // Read Memory Array Command
        input [`ADDRBUS_dim - 1:0] addr;

        begin
                fork
                 #5   AddrOut   = `ADDRBUS_dim'hZZZZZZZ;
                 #5   DataOut   = `DATABUS_dim'hzzzz;
                 #5   Write     = 1'b1;
                 #5   Read      = 1'b1;
                 #5   Enable    = 1'b1;
                  #5   Latch     = 1'b0;

                join

        #50    AddrOut= addr;  
        #5    Enable = 1'b0;
//!        #3    Latch  = 1'b0;
              Write  = 1'b0;
//!        #10    Latch  = 1'b1;
        #10   DataOut= `DATABUS_dim'hFFFF;      
//!              AddrOut   = `ADDRBUS_dim'hZZZZZZ;
        #50   Write = 1'b1;
        #0    Enable = 1'b1;
        #5    DataOut   = `DATABUS_dim'hzzzz;
             AddrOut   = `ADDRBUS_dim'hZZZZZZ;

        #1000 ;
        end
        endtask

        task read_array_nd;  // Read Memory Array Command
        input [`ADDRBUS_dim - 1:0] addr;

        begin
                fork
                 //#5   AddrOut   = `ADDRBUS_dim'hZZZZZZZ;
                 #5   DataOut   = `DATABUS_dim'hzzzz;
                 #5   Write     = 1'b1;
                 #5   Read      = 1'b1;
                 #5   Enable    = 1'b1;
                  #5   Latch     = 1'b0;

                join

        #50    AddrOut= addr;  
        #3    Latch  = 1'b0;
        #10    Latch  = 1'b1;
        #3    Latch  = 1'b0;
        #5    Enable = 1'b0;
              Write  = 1'b0;
           DataOut= `DATABUS_dim'h00FF;      
 //       #10   DataOut= `DATABUS_dim'hFFFF;      
//!              AddrOut   = `ADDRBUS_dim'hZZZZZZ;
        #50   Write = 1'b1;
        #0    Enable = 1'b1;
#0    DataOut   = `DATABUS_dim'hzzzz;
          //   AddrOut   = `ADDRBUS_dim'hZZZZZZ;

//        #1000 ;
        end
        endtask

        task toggle_adv_nd;  // Read Memory Array Command
        input [`ADDRBUS_dim - 1:0] addr;

        begin
                fork
           //      #5   AddrOut   = `ADDRBUS_dim'hZZZZZZZ;
                 #5   DataOut   = `DATABUS_dim'hzzzz;
                 #5   Write     = 1'b1;
                 #5   Read      = 1'b1;
                 #5   Enable    = 1'b1;
                  #5   Latch     = 1'b0;

                join

        #50    AddrOut= addr;  
        #5    Enable = 1'b0;
        #3    Latch  = 1'b1;
//              Write  = 1'b0;
        #10    Latch  = 1'b0;
        #10   DataOut= `DATABUS_dim'hFFFF;      
//!              AddrOut   = `ADDRBUS_dim'hZZZZZZ;
        #50   Write = 1'b1;
        #0    Enable = 1'b1;
        #5    DataOut   = `DATABUS_dim'hzzzz;
         //    AddrOut   = `ADDRBUS_dim'hZZZZZZ;

//        #1000 ;
        end
        endtask



//------------------------------------------
//   proc read_status_register 
//   write  BKA FFh read BKA SRD
//------------------------------------------

        task read_status_register;  // 

        input [`ADDRBUS_dim - 1:0] addr;

        begin
                fork
                 #5   AddrOut   = `ADDRBUS_dim'hZZZZZZ;
                 #5   DataOut   = `DATABUS_dim'hzzzz;
                 #5   Write     = 1'b1;
                 #5   Read      = 1'b1;
                 #5   Enable    = 1'b1;
                 #5   Latch     = 1'b1;
                join

        #50   AddrOut= addr;  
        #30   Enable = 1'b0;
        #3    Latch  = 1'b0;
              Write  = 1'b0;
        #10    Latch  = 1'b1;
        #10   DataOut= `DATABUS_dim'h0070;      
        #50   Write = 1'b1;
        #0    Enable = 1'b1;
        #5    DataOut   = `DATABUS_dim'hzzzz;
        #1000 ;
        end
        endtask

//------------------------------------------
// Page Read
//-----------------------------------------

        task page_read;

          input [`ADDRBUS_dim - 1:0] addr;
           reg [`ADDRBUS_dim - 1 : 0] B;
           integer i;
        begin

                fork
                 #5   AddrOut   = `ADDRBUS_dim'hZZZZZZ;
                 #5   DataOut   = `DATABUS_dim'hzzzz;
                 #5   Write     = 1'b1;
                 #5   Read      = 1'b1;
                 #5   Enable    = 1'b1;
                 #5   Latch     = 1'b1;
                join
 
        #50     AddrOut   = addr;
                B = {addr[`ADDRBUS_dim - 1:4], 4'b0} ;
        #2     Enable = 1'b0;
        #0      Latch  = 1'b0;                           
        #10      Latch  = 1'b1;                      //t_ELLH=, t_LLH=7, t_AVLH=7
         #80       Read   = 1'b0;
                for(i = 0; i < 17; i = i+1)
        #220    AddrOut= addr + i;

        #120     Read   = 1'b1;
        #5     Enable = 1'b1;                       
        #100     DataOut   = `DATABUS_dim'hzzzz;      //t_EHQZ=14
        #1000 ;
       
        end
        endtask
//------------------------------------------
        
//------------------------------------------
//   proc block_lock {}
//   write 60h 01h
//-----------------------------------------
// Block Lock

        task block_lock;
        
        input [`ADDRBUS_dim - 1 : 0] addr;
        
        begin

                fork
                 #5   AddrOut   = `ADDRBUS_dim'hZZZZZZ;
                 #5   DataOut   = `DATABUS_dim'hzzzz;
                 #5   Write     = 1'b1;
                 #5   Read      = 1'b1;
                 #5   Enable    = 1'b1;
                 #5   Latch     = 1'b1;
                join

        #50    AddrOut= addr;    
        #5    Enable = 1'b0;
        #3    Latch  = 1'b0;
              Write  = 1'b0;
        #10    Latch  = 1'b1;
        #10   DataOut= `DATABUS_dim'h0060;     
              AddrOut   = `ADDRBUS_dim'hZZZZZZ;
        #50   Write  = 1'b1;
              Enable = 1'b1;
        #10   DataOut= `DATABUS_dim'hzzzz;
        #40      AddrOut= addr;                   // Any address in the block
        #30   Enable = 1'b0;                   //t_ELEH=40
        #3    Latch  = 1'b0;
              Write  = 1'b0;                 
        #7    Latch  = 1'b1;
        #10   DataOut= `DATABUS_dim'h0001;
              AddrOut   = `ADDRBUS_dim'hZZZZZZ;
        #50   Write  = 1'b1;                  //t_WHEL=20, t_DVEH=40
              Enable = 1'b1;
        #10   DataOut= `DATABUS_dim'hzzzz;
        #1000 ;
        end
        endtask

//------------------------------------------
//   proc block_lock down {}
//   write 60h 2Fh
//-----------------------------------------
// Block Lock down

        task block_lock_down;
        
        input [`ADDRBUS_dim - 1 : 0] addr;
        
        begin

                fork
                 #5   AddrOut   = `ADDRBUS_dim'hZZZZZZ;
                 #5   DataOut   = `DATABUS_dim'hzzzz;
                 #5   Write     = 1'b1;
                 #5   Read      = 1'b1;
                 #5   Enable    = 1'b1;
                 #5   Latch     = 1'b1;
                join

        #50    AddrOut= addr;    
        #5    Enable = 1'b0;
        #3    Latch  = 1'b0;
              Write  = 1'b0;
        #10    Latch  = 1'b1;
        #10   DataOut= `DATABUS_dim'h0060;     
        #50   Write  = 1'b1;
              Enable = 1'b1;
        #10   DataOut= `DATABUS_dim'hzzzz;
              AddrOut   = `ADDRBUS_dim'hZZZZZZ;
        #40     AddrOut= addr;                   // Any address in the block
        #10   Enable = 1'b0;                   //t_ELEH=40
        #3    Latch  = 1'b0;
              Write  = 1'b0;                 
        #10    Latch  = 1'b1;
        #10   DataOut= `DATABUS_dim'h002F;
        #50   Write  = 1'b1;                  //t_WHEL=20, t_DVEH=40
              Enable = 1'b1;
        #10   DataOut= `DATABUS_dim'hzzzz;
               AddrOut   = `ADDRBUS_dim'hZZZZZZ;
        #1000 ;
        end
        endtask



//------------------------------------------
//   proc clear status_register 
//   write  50h
//-----------------------------------------
// Clear Status Register

        task clear_status;

        begin
               fork
                 #5   AddrOut   = `ADDRBUS_dim'hZZZZZZ;
                 #5   DataOut   = `DATABUS_dim'hzzzz;
                 #5   Write     = 1'b1;
                 #5   Read      = 1'b1;
                 #5   Enable    = 1'b1;
                 #5   Latch     = 1'b1;
                join
 
        #50    AddrOut= `ADDRBUS_dim'h000000;  
        #5    Enable = 1'b0;
        #3    Latch  = 1'b0;
              Write  = 1'b0;
        #10    Latch  = 1'b1;
        #10   DataOut= `DATABUS_dim'h0050;      
        #50   Write = 1'b1;
        #5    Enable = 1'b1;
        #5    DataOut   = `DATABUS_dim'hzzzz;
              AddrOut   = `ADDRBUS_dim'hZZZZZZ;
        #1000 ;
        end
        endtask


//------------------------------------------
//   proc block_unlock {}
//   write 60h D0h
//-----------------------------------------
// Block UnLock

        task block_unLock;
        
        input [`ADDRBUS_dim - 1:0] addr;
        begin
                fork
                 #5   AddrOut   = `ADDRBUS_dim'hZZZZZZ;
                 #5   DataOut   = `DATABUS_dim'hzzzz;
                 #5   Write     = 1'b1;
                 #5   Read      = 1'b1;
                 #5   Enable    = 1'b1;
                 #5   Latch     = 1'b1;
                join

        #50    AddrOut= addr; 
               Write  = 1'b0;

        #5    Enable = 1'b0;
        #3    Latch  = 1'b0;
              Write  = 1'b0;
        #10    Latch  = 1'b1;
        #10   DataOut= `DATABUS_dim'h0060;     
        #50   Write  = 1'b1;
              Enable = 1'b1;
        #10   DataOut= `DATABUS_dim'hzzzz;
              AddrOut   = `ADDRBUS_dim'hZZZZZZ;
        #40   AddrOut= addr;                   // Any address in the block
        #5    Enable = 1'b0;                   //t_ELEH=40
        #3    Latch  = 1'b0;
              Write  = 1'b0;                 
        #10    Latch  = 1'b1;
        #10   DataOut= `DATABUS_dim'h00D0;
        #50   Write  = 1'b1;                  //t_WHEL=20, t_DVEH=40
        #5     Enable = 1'b1;
        #10   DataOut= `DATABUS_dim'hzzzz;
              AddrOut   = `ADDRBUS_dim'hZZZZZZ; 
        #1000 ;

        end
        endtask

        task block_unLock_nd;
        
        input [`ADDRBUS_dim - 1:0] addr;
        begin
                fork
               //  #5   AddrOut   = `ADDRBUS_dim'hZZZZZZ;
                 #5   DataOut   = `DATABUS_dim'hzzzz;
                 #5   Write     = 1'b1;
                 #5   Read      = 1'b1;
                 #5   Enable    = 1'b1;
                 #5   Latch     = 1'b0;
                join

        #50    AddrOut= addr; 
               Write  = 1'b0;

        #5    Enable = 1'b0;
//        #3    Latch  = 1'b0;
              Write  = 1'b0;
//        #10    Latch  = 1'b1;
        #10   DataOut= `DATABUS_dim'h0060;     
        #50   Write  = 1'b1;
              Enable = 1'b1;
//        #10   DataOut= `DATABUS_dim'hzzzz;
         //     AddrOut   = `ADDRBUS_dim'hZZZZZZ;
//        #40   AddrOut= addr;                   // Any address in the block
        #5    Enable = 1'b0;                   //t_ELEH=40
//        #3    Latch  = 1'b0;
              Write  = 1'b0;                 
//        #10    Latch  = 1'b1;
        #10   DataOut= `DATABUS_dim'h00D0;
        #50   Write  = 1'b1;                  //t_WHEL=20, t_DVEH=40
        #5     Enable = 1'b1;
        #10   DataOut= `DATABUS_dim'hzzzz;
        //      AddrOut   = `ADDRBUS_dim'hZZZZZZ; 
//        #1000 ;

        end
        endtask



    
//------------------------------------------
//   proc program_ suspend
//   write  B0h
//-----------------------------------------
 // Program/Erase Suspend
 
        task program_suspend;

        begin
                 fork
                 #5   AddrOut   = `ADDRBUS_dim'hZZZZZZ;
                 #5   DataOut   = `DATABUS_dim'hzzzz;
                 #5   Write     = 1'b1;
                 #5   Read      = 1'b1;
                 #5   Enable    = 1'b1;
                 #5   Latch     = 1'b1;
                join
                
        #50    AddrOut= `ADDRBUS_dim'h000000;  
        #5    Enable = 1'b0;
        #3    Latch  = 1'b0;
              Write  = 1'b0;
        #10   Latch  = 1'b1;
        #10   DataOut= `DATABUS_dim'h00B0;      
        #50   Write = 1'b1;
        #5    Enable = 1'b1;
        #5    DataOut   = `DATABUS_dim'hzzzz;
              AddrOut   = `ADDRBUS_dim'hZZZZZZ;
        #1000 ;
        
        end
        endtask


//------------------------------------------
//   proc read_CFI_Query 
//   write  BKA 98h read BKA QD
//-----------------------------------------
// Read CFI_Query
 
        task read_CFI_Query;
        input [`ADDRBUS_dim - 1 : 0] addr;

        begin
                 fork
                 #5   AddrOut   = `ADDRBUS_dim'hZZZZZZ;
                 #5   DataOut   = `DATABUS_dim'hzzzz;
                 #5   Write     = 1'b1;
                 #5   Read      = 1'b1;
                 #5   Enable    = 1'b1;
                 #5   Latch     = 1'b1;
                join

        #50    AddrOut= addr;                         //Block address  
        #10   Enable = 1'b0;
        #3    Latch  = 1'b0;
              Write  = 1'b0;
        #10    Latch  = 1'b1;
        #10   DataOut= `DATABUS_dim'h0098;  
        #50   Write = 1'b1;
        #5    Enable = 1'b1;
        #5    DataOut   = `DATABUS_dim'hzzzz;
              AddrOut   = `ADDRBUS_dim'hZZZZZZ;
        

        #1000 ;
        end
        endtask



//------------------------------------------
//   proc read_electronic_signature 
//   write  BKA 90h read BKA ESD
//-----------------------------------------
// Read Electronic Signature

        task read_signature;

        input [`ADDRBUS_dim - 1 : 0] addr;

        begin

                fork
                 #5   AddrOut   = `ADDRBUS_dim'hZZZZZZ;
                 #5   DataOut   = `DATABUS_dim'hzzzz;
                 #5   Write     = 1'b1;
                 #5   Read      = 1'b1;
                 #5   Enable    = 1'b1;
                 #5   Latch     = 1'b1;
                join
   
        #50   AddrOut= addr;                         //Block address  
        #5    Enable = 1'b0;
        #3    Latch  = 1'b0;
              Write  = 1'b0;
        #10    Latch  = 1'b1;
        #10   DataOut= `DATABUS_dim'h0090;      
        #50   Write = 1'b1;
        #0    Enable = 1'b1;
        #5    DataOut   = `DATABUS_dim'hzzzz;
              AddrOut   = `ADDRBUS_dim'hZZZZZZ;

        #1000 ;

        end
        endtask

        task read_signature_nd;

        input [`ADDRBUS_dim - 1 : 0] addr;

        begin

                fork
           //      #5   AddrOut   = `ADDRBUS_dim'hZZZZZZ;
                 #5   DataOut   = `DATABUS_dim'hzzzz;
                 #5   Write     = 1'b1;
                 #5   Read      = 1'b1;
                 #5   Enable    = 1'b1;
//                 #5   Latch     = 1'b1;
                join
   
        //#50   AddrOut= addr;                         //Block address  
           AddrOut= addr;                         //Block address  
        #5    Enable = 1'b0;
//        #3    Latch  = 1'b0;
              Write  = 1'b0;
//        #10    Latch  = 1'b1;
        #10   DataOut= `DATABUS_dim'h0090;      
        #50   Write = 1'b1;
        #0    Enable = 1'b1;
        #5    DataOut   = `DATABUS_dim'hzzzz;
          //    AddrOut   = `ADDRBUS_dim'hZZZZZZ;

//        #1000 ;

        end
        endtask

//------------------------------------------
//   proc read_status_register 
//   write  BKA 70h read BKA SRD
//-----------------------------------------
// Read Status Register

        task read_status;

        input [`ADDRBUS_dim - 1 : 0] addr;
        begin
                 fork
                 #5   AddrOut   = `ADDRBUS_dim'hZZZZZZ;
                 #5   DataOut   = `DATABUS_dim'hzzzz;
                 #5   Write     = 1'b1;
                 #5   Read      = 1'b1;
                 #5   Enable    = 1'b1;
                 #5   Latch     = 1'b1;
                join

        #50    AddrOut= addr;                         //Block address  
        #5    Enable = 1'b0;
        #3    Latch  = 1'b0;
              Write  = 1'b0;
        #7    Latch  = 1'b1;
        #10   DataOut= `DATABUS_dim'h0070;      
        #50   Write = 1'b1;
        #0    Enable = 1'b1;
        #5    DataOut   = `DATABUS_dim'hzzzz;
              AddrOut   = `ADDRBUS_dim'hZZZZZZ; 
        #50    AddrOut   = addr;
        #5    Enable = 1'b0;
        #3    Latch  = 1'b0;                           
        #7    Latch  = 1'b1;                      //t_ELLH=10, t_LLH=7
              Read   = 1'b0;
        #35    Read   = 1'b1;
        #5    Enable = 1'b1;                       
        #10   DataOut   = `DATABUS_dim'hzzzz;      //t_EHQZ=14
               AddrOut   = `ADDRBUS_dim'hZZZZZZ;

        #1000 ;
        end
        endtask


//------------------------------------------
//   proc program_resume 
//   write  D0h
//-----------------------------------------
// Program/Erase Resume
        
        task program_resume;

        begin
                 fork
                 #5   AddrOut   = `ADDRBUS_dim'hZZZZZZ;
                 #5   DataOut   = `DATABUS_dim'hzzzz;
                 #5   Write     = 1'b1;
                 #5   Read      = 1'b1;
                 #5   Enable    = 1'b1;
                 #5   Latch     = 1'b1;
                join

        #50    AddrOut= `ADDRBUS_dim'h000000;
        #5    Enable = 1'b0;
        #3    Latch  = 1'b0;
              Write  = 1'b0;
        #10   Latch  = 1'b1;
        #10   DataOut= `DATABUS_dim'h00D0;      
        #50   Write = 1'b1;
        #0    Enable = 1'b1;
        #5    DataOut   = `DATABUS_dim'hzzzz;
              AddrOut   = `ADDRBUS_dim'hZZZZZZ;
        #1000 ;
        end
        endtask


//------------------------------------------
//   proc protection_register_program {}{}
//   write PRA C0h
//-----------------------------------------
// Protection Register Program

        task protection_register;

        input [`ADDRBUS_dim - 1 : 0] addr;
        input [`DATABUS_dim - 1 : 0] data;

        begin
                 fork
                 #5   AddrOut   = `ADDRBUS_dim'hZZZZZZ;
                 #5   DataOut   = `DATABUS_dim'hzzzz;
                 #5   Write     = 1'b1;
                 #5   Read      = 1'b1;
                 #5   Enable    = 1'b1;
                 #5   Latch     = 1'b1;
                join

        #50   AddrOut=addr ;    
        #5    Enable = 1'b0;
        #3    Latch  = 1'b0;
              Write  = 1'b0;
        #10   Latch  = 1'b1;
        #10   DataOut= `DATABUS_dim'h00C0;     
        #50   Write  = 1'b1;
              Enable = 1'b1;
        #10   DataOut= `DATABUS_dim'hzzzz;
              AddrOut   = `ADDRBUS_dim'hZZZZZZ;  
        #40   AddrOut=addr ;                   // Any address in the block
        #30   Enable = 1'b0;                   //t_ELEH=40
        #3    Latch  = 1'b0;
              Write  = 1'b0;                 
        #10   Latch  = 1'b1;
        #10   DataOut= data;
        #50   Write  = 1'b1;                  //t_WHEL=20, t_DVEH=40
              Enable = 1'b1;
        #10   DataOut= `DATABUS_dim'hzzzz;
              AddrOut   = `ADDRBUS_dim'hZZZZZZ;
        #1000 ;



        end
        endtask

//------------------------------------------
//   proc set_configuration_register {}{}
//   write CRD 60h CRD 03h
//-----------------------------------------

        task set_configuration_register;

        input [`ADDRBUS_dim - 1 : 0] addr;

        begin
                 fork
                 #5   AddrOut   = `ADDRBUS_dim'hZZZZZZ;
                 #5   DataOut   = `DATABUS_dim'hzzzz;
                 #5   Write     = 1'b1;
                 #5   Read      = 1'b1;
                 #5   Enable    = 1'b1;
                 #5   Latch     = 1'b1;
                join

        #50    AddrOut=addr ;    
        #5    Enable = 1'b0;
        #3    Latch  = 1'b0;
              Write  = 1'b0;
        #10    Latch  = 1'b1;
        #10   DataOut= `DATABUS_dim'h0060;     
        #50   Write  = 1'b1;
              Enable = 1'b1;
        #10   DataOut= `DATABUS_dim'hzzzz;
              AddrOut   = `ADDRBUS_dim'hZZZZZZ;
        #40      AddrOut=addr ;                   // Any address in the block
        #10   Enable = 1'b0;                   //t_ELEH=40
        #3    Latch  = 1'b0;
              Write  = 1'b0;                 
        #10    Latch  = 1'b1;
        #10   DataOut= `DATABUS_dim'h0003;
        #50   Write  = 1'b1;                  //t_WHEL=20, t_DVEH=40
              Enable = 1'b1;
        #10   DataOut= `DATABUS_dim'hzzzz;
              //AddrOut   = `ADDRBUS_dim'hZZZZZZ;
        #1000 ;
        end
        endtask

 task setup_befprogram;

        input [`ADDRBUS_dim - 1 : 0] addr1;
        
        begin
                 fork
                 #5   AddrOut   = `ADDRBUS_dim'hZZZZZZ;
                 #5   DataOut   = `DATABUS_dim'hzzzz;
                 #5   Write     = 1'b1;
                 #5   Read      = 1'b1;
                 #5   Enable    = 1'b1;
                 #5   Latch     = 1'b1;
                join

        #50   AddrOut=addr1 ;    
        #40   Enable = 1'b0;
        #3    Latch  = 1'b0;
              Write  = 1'b0;
        #10   Latch  = 1'b1;
        #10   DataOut= `DATABUS_dim'h0080;     
        #50   Write  = 1'b1;
              Enable = 1'b1;
        #10   DataOut= `DATABUS_dim'hzzzz;
              AddrOut   = `ADDRBUS_dim'hZZZZZZ;
        #40   AddrOut=addr1 ;                   // WA1
        #40   Enable = 1'b0;                   //t_ELEH=40
        #3    Latch  = 1'b0;
              Write  = 1'b0;                 
        #10   Latch  = 1'b1;
        #10   DataOut= `DATABUS_dim'h00D0;     
        #50   Write  = 1'b1;                  //t_WHEL=20, t_DVEH=40
              Enable = 1'b1;
        #10   DataOut= `DATABUS_dim'hzzzz;
             AddrOut   = `ADDRBUS_dim'hZZZZZZ;
        end
        endtask


//-----------------------------------------------------------------------------------
//   verify_exit_program {addr1}{addr2}{addr3}{addrn}{addrnot1} {data1}{datan}
//   write WA1 PD1, WA2 PD2, WA3 PD3, WAn PDn, notWA1 FFFFh
//        VPP=12.0;

        task verify_exit_program;

       
        input [`ADDRBUS_dim - 1 : 0] addr1;
        input [`DATABUS_dim - 1 : 0] data1;
        input [`ADDRBUS_dim - 1 : 0] addr2;
        input [`DATABUS_dim - 1 : 0] data2;
        input [`ADDRBUS_dim - 1 : 0] addr3;
        input [`DATABUS_dim - 1 : 0] data3;
        input [`ADDRBUS_dim - 1 : 0] addrn;
        input [`DATABUS_dim - 1 : 0] datan;
        input [`ADDRBUS_dim - 1 : 0] notaddr1;
        
        begin
                 fork
                 #5   AddrOut   = `ADDRBUS_dim'hZZZZZZ;
                 #5   DataOut   = `DATABUS_dim'hzzzz;
                 #5   Write     = 1'b1;
                 #5   Read      = 1'b1;
                 #5   Enable    = 1'b1;
                 #5   Latch     = 1'b1;
                join

        #50   AddrOut=addr1 ;    
        #5    Enable = 1'b0;
        #3    Latch  = 1'b0;
              Write  = 1'b0;
        #10   Latch  = 1'b1;
        #10   DataOut= data1;     
              AddrOut   = `ADDRBUS_dim'hZZZZZZ;
        #50   Write  = 1'b1;
              Enable = 1'b1;
        #10   DataOut= `DATABUS_dim'hzzzz;
        #(`WordProgram_time ) ;
        #40   AddrOut=addr2 ;                   // WA1
        #5    Enable = 1'b0;                   //t_ELEH=40
        #3    Latch  = 1'b0;
              Write  = 1'b0;                 
        #10   Latch  = 1'b1;
        #10   DataOut= data2;     
              AddrOut   = `ADDRBUS_dim'hZZZZZZ;
        #50   Write  = 1'b1;                  //t_WHEL=20, t_DVEH=40
              Enable = 1'b1;
        #10   DataOut= `DATABUS_dim'hzzzz;
        #(`WordProgram_time ) ;
        #40   AddrOut=addr3 ;                   // WA1
        #5    Enable = 1'b0;                   //t_ELEH=40
        #3    Latch  = 1'b0;
              Write  = 1'b0;                 
        #10   Latch  = 1'b1;
        #10   DataOut= data3;
              AddrOut   = `ADDRBUS_dim'hZZZZZZ;
        #50   Write  = 1'b1;                  //t_WHEL=20, t_DVEH=40
              Enable = 1'b1;
        #10   DataOut= `DATABUS_dim'hzzzz;
        #(`WordProgram_time ) ;
        #40   AddrOut=addrn ;                   // WAn
        #5    Enable = 1'b0;                   //t_ELEH=40
        #3    Latch  = 1'b0;
              Write  = 1'b0;                 
        #10   Latch  = 1'b1;
        #10   DataOut= datan;
              AddrOut   = `ADDRBUS_dim'hZZZZZZ;
        #50   Write  = 1'b1;                  //t_WHEL=20, t_DVEH=40
              Enable = 1'b1;
        #10   DataOut= `DATABUS_dim'hzzzz;
        #(`WordProgram_time ) ;
        #40   AddrOut=notaddr1 ;                   // notWA1
        #5    Enable = 1'b0;                   //t_ELEH=40
        #3    Latch  = 1'b0;
              Write  = 1'b0;                 
        #10   Latch  = 1'b1;
        #10   DataOut=  `DATABUS_dim'hFFFF;
              AddrOut   = `ADDRBUS_dim'hZZZZZZ;
        #50   Write  = 1'b1;                  //t_WHEL=20, t_DVEH=40
              Enable = 1'b1;
        #10   DataOut= `DATABUS_dim'hzzzz;
        #(`WordProgram_time ) ;
        #500 ;
        end
        endtask
//-----------------------------------------------------------------------------------

//-----------------------------------------------------------------------------------
//   verify_exit_cmd {addr1}{addr2}{addr3}{addrn}{addrnot1} {data1}{datan}
//   write WA1 PD1, WA2 PD2, WA3 PD3, WAn PDn, notWA1 FFFFh
//        VPP=12.0;

        task verify_exit_cmd;

       
        input [`ADDRBUS_dim - 1 : 0] addr1;
        input [`DATABUS_dim - 1 : 0] data1;
        input [`ADDRBUS_dim - 1 : 0] addr2;
        input [`DATABUS_dim - 1 : 0] data2;
        input [`ADDRBUS_dim - 1 : 0] addr3;
        input [`DATABUS_dim - 1 : 0] data3;
        input [`ADDRBUS_dim - 1 : 0] addrn;
        input [`DATABUS_dim - 1 : 0] datan;
        input [`ADDRBUS_dim - 1 : 0] notaddr1;
        input [`ADDRBUS_dim - 1 : 0] notaddr2;
        input [`ADDRBUS_dim - 1 : 0] notaddr3;
        input [`ADDRBUS_dim - 1 : 0] notaddr4;
        
        begin
                 fork
                 #5   AddrOut   = `ADDRBUS_dim'hZZZZZZ;
                 #5   DataOut   = `DATABUS_dim'hzzzz;
                 #5   Write     = 1'b1;
                 #5   Read      = 1'b1;
                 #5   Enable    = 1'b1;
                 #5   Latch     = 1'b1;
                join

        #50   AddrOut=addr1 ;    
        #5    Enable = 1'b0;
        #3    Latch  = 1'b0;
              Write  = 1'b0;
        #10   Latch  = 1'b1;
        #10   DataOut= data1;     
              AddrOut   = `ADDRBUS_dim'hZZZZZZ;
        #50   Write  = 1'b1;
              Enable = 1'b1;
        #10   DataOut= `DATABUS_dim'hzzzz;
        #(`WordProgram_time ) ;
        #40   AddrOut=addr2 ;                   // WA1
        #5    Enable = 1'b0;                   //t_ELEH=40
        #3    Latch  = 1'b0;
              Write  = 1'b0;                 
        #10   Latch  = 1'b1;
        #10   DataOut= data2;     
              AddrOut   = `ADDRBUS_dim'hZZZZZZ;
        #50   Write  = 1'b1;                  //t_WHEL=20, t_DVEH=40
              Enable = 1'b1;
        #10   DataOut= `DATABUS_dim'hzzzz;
        #(`WordProgram_time ) ;
        #40   AddrOut=addr3 ;                   // WA1
        #5    Enable = 1'b0;                   //t_ELEH=40
        #3    Latch  = 1'b0;
              Write  = 1'b0;                 
        #10   Latch  = 1'b1;
        #10   DataOut= data3;
              AddrOut   = `ADDRBUS_dim'hZZZZZZ;
        #50   Write  = 1'b1;                  //t_WHEL=20, t_DVEH=40
              Enable = 1'b1;
        #10   DataOut= `DATABUS_dim'hzzzz;
        #(`WordProgram_time ) ;
        #40   AddrOut=addrn ;                   // WAn
        #5    Enable = 1'b0;                   //t_ELEH=40
        #3    Latch  = 1'b0;
              Write  = 1'b0;                 
        #10   Latch  = 1'b1;
        #10   DataOut= datan;
              AddrOut   = `ADDRBUS_dim'hZZZZZZ;
        #50   Write  = 1'b1;                  //t_WHEL=20, t_DVEH=40
              Enable = 1'b1;
        #10   DataOut= `DATABUS_dim'hzzzz;
        #(`WordProgram_time ) ;
        #40   AddrOut=notaddr1 ;                   // notWA1
        #5    Enable = 1'b0;                   //t_ELEH=40
        #3    Latch  = 1'b0;
              Write  = 1'b0;                 
        #10   Latch  = 1'b1;
        #10   DataOut=  `DATABUS_dim'hABCD;
              AddrOut   = `ADDRBUS_dim'hZZZZZZ;
        #50   Write  = 1'b1;                  //t_WHEL=20, t_DVEH=40
              Enable = 1'b1;
        #10   DataOut= `DATABUS_dim'hzzzz;
              AddrOut   = `ADDRBUS_dim'hZZZZZZ;
        #50   Write  = 1'b1;                  //t_WHEL=20, t_DVEH=40
              Enable = 1'b1;
        #10   DataOut= `DATABUS_dim'hzzzz;
        #40   AddrOut=addrn ;                   // WAn
        #5    Enable = 1'b0;                   //t_ELEH=40
        #3    Latch  = 1'b0;
              Write  = 1'b0;                 
        #10   Latch  = 1'b1;
        #10   DataOut= datan;
              AddrOut   = `ADDRBUS_dim'hZZZZZZ;
        #50   Write  = 1'b1;                  //t_WHEL=20, t_DVEH=40
              Enable = 1'b1;
        #10   DataOut= `DATABUS_dim'hzzzz;
        #40   AddrOut=notaddr1 ;                   // notWA1
        #5    Enable = 1'b0;                   //t_ELEH=40
        #3    Latch  = 1'b0;
              Write  = 1'b0;                 
        #10   Latch  = 1'b1;
        #10   DataOut=  `DATABUS_dim'hC1A0;
              AddrOut   = `ADDRBUS_dim'hZZZZZZ;
        #50   Write  = 1'b1;                  //t_WHEL=20, t_DVEH=40
              Enable = 1'b1;
        #10   DataOut= `DATABUS_dim'hzzzz;
        #40   AddrOut= notaddr2;                   // WAn
        #5    Enable = 1'b0;                   //t_ELEH=40
        #3    Latch  = 1'b0;
              Write  = 1'b0;                 
        #10   Latch  = 1'b1;
        #10   DataOut= datan;
              AddrOut   = `ADDRBUS_dim'hZZZZZZ;
        #50   Write  = 1'b1;                  //t_WHEL=20, t_DVEH=40
              Enable = 1'b1;
        #10   DataOut= `DATABUS_dim'hzzzz;
        #40   AddrOut=notaddr3;                   // notWA1
        #5    Enable = 1'b0;                   //t_ELEH=40
        #3    Latch  = 1'b0;
              Write  = 1'b0;                 
        #10   Latch  = 1'b1;
        #10   DataOut=  `DATABUS_dim'h6789;
              AddrOut   = `ADDRBUS_dim'hZZZZZZ;
        #50   Write  = 1'b1;                  //t_WHEL=20, t_DVEH=40
              Enable = 1'b1;
        #10   DataOut= `DATABUS_dim'hzzzz;
              AddrOut   = `ADDRBUS_dim'hZZZZZZ;
        #50   Write  = 1'b1;                  //t_WHEL=20, t_DVEH=40
              Enable = 1'b1;
        #10   DataOut= `DATABUS_dim'hzzzz;
        #40   AddrOut=notaddr4 ;                   // notWA1
        #5    Enable = 1'b0;                   //t_ELEH=40
        #3    Latch  = 1'b0;
              Write  = 1'b0;                 
        #10   Latch  = 1'b1;
        #10   DataOut=  `DATABUS_dim'hffff;
              AddrOut   = `ADDRBUS_dim'hZZZZZZ;
        #50   Write  = 1'b1;                  //t_WHEL=20, t_DVEH=40
              Enable = 1'b1;
        #10   DataOut= `DATABUS_dim'hzzzz;

        #1000 ;
        end
        endtask

//#############################################################
// Write to Buffer and Program 

        task buffer_program;
              input [`ADDRBUS_dim-1 : 0]  addr;
              input integer N;

              integer i;


        begin
                fork
                 #5   AddrOut   = `ADDRBUS_dim'hZZZZZZ;
                 #5   DataOut   = `DATABUS_dim'hzzzz;
                 #5   Write     = 1'b1;
                 #5   Read      = 1'b1;
                 #5   Enable    = 1'b1;
                 #5   Latch     = 1'b0;
                join
                
        #100  AddrOut= addr;
        #100  Enable = 1'b0;
              Write  = 1'b0;
        #50   DataOut= `DATABUS_dim'h00E8;    
                #5    Enable = 1'b1;
                #100  Write  = 1'b1;


        #20   DataOut= `DATABUS_dim'hzzzz;
        #5    Enable = 1'b0;
              Write  = 1'b0;
      
        #50   DataOut= N;       
        #10   AddrOut= addr;
        
        #5    Enable = 1'b1;
        #100  Write  = 1'b1;
        #20   DataOut= `DATABUS_dim'hzzzz;
              AddrOut   = `ADDRBUS_dim'hZZZZZZ;
        
        for (i=0 ; i<=N ; i=i+1) begin
               #5    Enable = 1'b0;

                    Write  = 1'b0;
    
               #10 AddrOut = addr+i;

                #50 DataOut = i;
                           #5    Enable = 1'b1;
#100  Write  = 1'b1;

             #20   DataOut= `DATABUS_dim'hzzzz;
                   AddrOut = `ADDRBUS_dim'hZZZZZZ;
        end     

        
       //confirm
        #100  AddrOut= `ADDRBUS_dim'h000000;    
        #100  Write  = 1'b0;
        #5    Enable = 1'b0;
        #50   DataOut= `DATABUS_dim'h00D0;      
        
       
#100  Write  = 1'b1;
        #20   DataOut= `DATABUS_dim'hzzzz;
               AddrOut = `ADDRBUS_dim'hZZZZZZ;
#5    Enable = 1'b1;
        #1000 ;

        end
        endtask


          task buffer_program_prova;
              input [`ADDRBUS_dim-1 : 0]  addr;
              input integer N;

              integer i;


        begin
                fork
                 #5   AddrOut   = `ADDRBUS_dim'hZZZZZZ;
                 #5   DataOut   = `DATABUS_dim'hzzzz;
                 #5   Write     = 1'b1;
                 #5   Read      = 1'b1;
                 #5   Enable    = 1'b1;
                 #5   Latch     = 1'b0;
                join
                
        #100  AddrOut= addr;
        #15  Enable = 1'b0;
           DataOut= `DATABUS_dim'h00E8;
           //aggiunta
           #15  Write  = 1'b0;

        #60  Write  = 1'b1;
        #15    Enable = 1'b1;

         #21   DataOut= `DATABUS_dim'hzzzz;
         
        #10   AddrOut= addr;
        //aggiunta
        #15  Enable = 1'b0;
             DataOut= N;  
          #15  Write  = 1'b0;
          #60  Write  = 1'b1;
        #15    Enable = 1'b1;

        
        
        #21   DataOut= `DATABUS_dim'hzzzz;
        
        for (i=0 ; i<=N ; i=i+1) begin
    
               #10 AddrOut = addr+i;

               #15  Enable = 1'b0;

                 DataOut = i;
              #15  Write  = 1'b0;
          #60  Write  = 1'b1;
        #15    Enable = 1'b1;

             #21   DataOut= `DATABUS_dim'hzzzz;
        end     

        
       //confirm
        #100  AddrOut= `ADDRBUS_dim'h000000;  
        #15  Enable = 1'b0;
             DataOut= `DATABUS_dim'h00D0; 
          #15  Write  = 1'b0;
          #60  Write  = 1'b1;
        #15    Enable = 1'b1;
   
       
        #21   DataOut= `DATABUS_dim'hzzzz;
        #1000 ;

        end
        endtask

///////////////////////////////////////////////////////////////////
   task burst;
       
        input [`ADDRBUS_dim - 1 : 0] addr;

        begin 
                 fork
                 #5  AddrOut   = `ADDRBUS_dim'hZZZZZZ;
                 #5   DataOut   = `DATABUS_dim'hzzzz;
                 #5   Write     = 1'b1;
                 #5   Read      = 1'b1;
                 #5   Enable    = 1'b1;
                 #5   Latch     = 1'b1;
                join
           
        #50   AddrOut = addr;
        #10   Enable  = 1'b0;
        #30   Latch   = 1'b0;
        #20   Latch   = 1'b1;
              Read    = 1'b0;
        #1000 Read    = 1'b1;
        #14  Enable  = 1'b1;
        #1000;
  
        end           
    endtask

   task burst_debug;
       
        input [`ADDRBUS_dim - 1 : 0] addr;

        begin 
                 fork
                 #5  AddrOut   = `ADDRBUS_dim'hZZZZZZ;
                 #5   DataOut   = `DATABUS_dim'hzzzz;
                 #5   Write     = 1'b1;
                 #5   Read      = 1'b1;
                 #5   Enable    = 1'b1;
                 #0   Latch     = 1'b1;
                join
           
        #45   AddrOut = addr;
        #0  Enable  = 1'b0;
     //   #30   Latch   = 1'b0;
        #0   Latch   = 1'b0;
        #20   Latch   = 1'b1;
        #20      Read    = 1'b0;
        #1000 Read    = 1'b1;
        #14  Enable  = 1'b1;
        #1000;
  
        end           
    endtask
`ifdef DEBUG
   task burst_debug_with_clock;
       
        input [`ADDRBUS_dim - 1 : 0] addr;

        begin 
                 fork
                 //#5  AddrOut   = `ADDRBUS_dim'hZZZZZZ;
                 #5   DataOut   = `DATABUS_dim'hzzzz;
                 #5   Write     = 1'b1;
                 #5   Read      = 1'b1;
                 #5   Enable    = 1'b1;
                 #0   Latch     = 1'b1;
                join
           
        #45   ;
     //   #30   Latch   = 1'b0;
        #0  Enable  = 1'b0;
        #0 Clock = 1'b1;
        #0 Clock = 1'b1;
        #0 Clock = 1'b1;
        #0 Clock = 1'b1;
        #4   Latch   = 1'b0;
        #0   Latch   = 1'b0;
#0        AddrOut = addr;
        #10 Clock = 1'b0;
        #10   Latch   = 1'b1;
        #0 Clock = 1'b1;
        #20      Read    = 1'b0;
        #1000 Read    = 1'b1;
        #14  Enable  = 1'b1;
        #1000;
  
        end           
    endtask
`endif


task burst_err;
       
        input [`ADDRBUS_dim - 1 : 0] addr;

        begin 
                 fork
                 #5   AddrOut   = `ADDRBUS_dim'hZZZZZZ;
                 #5   DataOut   = `DATABUS_dim'hzzzz;
                 #5   Write     = 1'b1;
                 #5   Read      = 1'b1;
                 #5   Enable    = 1'b1;
                 #5   Latch     = 1'b1;
                join
        #10   Enable  = 1'b0;
        #50   AddrOut = addr;
        #30   Latch   = 1'b0;
        #100  Latch   = 1'b1;
        #5   AddrOut   = `ADDRBUS_dim'hZZZZZZ;
              Read    = 1'b0;
        #1000 Read    = 1'b1;
        #10   Enable  = 1'b1;
        end           
    endtask

 task burst_suspend;
       
        input [`ADDRBUS_dim - 1 : 0] addr;

        begin 
                 fork
                 #5   AddrOut   = `ADDRBUS_dim'hZZZZZZ;
                 #5   DataOut   = `DATABUS_dim'hzzzz;
                 #5   Write     = 1'b1;
                 #5   Read      = 1'b1;
                 #5   Enable    = 1'b1;
                 #5   Latch     = 1'b1;
                join
        #10   Enable  = 1'b0;
        #50   AddrOut = addr;
        #30   Latch   = 1'b0;
        #100  Latch   = 1'b1;
              Read    = 1'b0;
        #1000 Read    = 1'b1;
        #50   Read    = 1'b0;
        #1000 Read    = 1'b1;
        #10   Enable  = 1'b1;
        end           
    endtask

 task burst_g_suspend;
       
        input [`ADDRBUS_dim - 1 : 0] addr;

        begin 
                 fork
                 #5   AddrOut   = `ADDRBUS_dim'hZZZZZZ;
                 #5   DataOut   = `DATABUS_dim'hzzzz;
                 #5   Write     = 1'b1;
                 #5   Read      = 1'b1;
                 #5   Enable    = 1'b1;
                 #5   Latch     = 1'b1;
                join
        #10   Enable  = 1'b0;
        #50   AddrOut = addr;
        #30   Latch   = 1'b0;
        #100  Latch   = 1'b1;
              Read    = 1'b0;
        #150  Read    = 1'b1;
        #200  Read    = 1'b0;
        #1000 Read    = 1'b1;
        #10   Enable  = 1'b1;
        end           
    endtask

endmodule

